﻿using Quartz;
using Quartz.Impl;
using Quartz.Impl.Triggers;
using System;
using System.Threading.Tasks;

namespace S2_Xxxx_XxxNetApi
{
    /// <summary>
    /// Quartz帮助类
    /// </summary>
    public class QuartzHelper
    {
        private static ISchedulerFactory _schedulerFactory;
        private static IScheduler _scheduler;

        /// <summary>
        /// 构造函数
        /// </summary>
        static QuartzHelper()
        {
            _schedulerFactory = CreateSchedulerFactory();
            GetScheduler();
        }

        #region 获取服务器使用的调度程序
        /// <summary>
        /// 获取服务器使用的调度程序。
        /// </summary>
        /// <returns></returns>
        protected static async Task GetScheduler()
        {
            _scheduler = await _schedulerFactory.GetScheduler();
        }
        #endregion

        #region 创建调度器工厂
        /// <summary>
        /// 创建调度器工厂。
        /// </summary>
        /// <returns></returns>
        protected static ISchedulerFactory CreateSchedulerFactory()
        {
            return new StdSchedulerFactory();
        }
        #endregion

        #region 委托调度器，启动实例
        /// <summary>
        /// 委托调度器，启动实例。
        /// </summary>
        public static void Start()
        {
            try
            {
                _scheduler.Start();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region 委托调度器，停止实例
        /// <summary>
        ///  委托调度器，停止实例。
        /// </summary>
        public static void Stop()
        {
            try
            {
                if (!_scheduler.IsShutdown)
                    _scheduler.Shutdown(true);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region 暂停调度器中所有的活动
        /// <summary>
        /// 暂停调度器中所有的活动。
        /// </summary>
        public static void Pause()
        {
            try
            {
                _scheduler.PauseAll();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region 恢复所有活动
        /// <summary>
        /// 恢复所有活动。
        /// </summary>
        public static void Resume()
        {
            try
            {
                _scheduler.ResumeAll();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region 添加任务(任务间隔时间单位：小时)
        /// <summary>
        /// 添加任务(任务间隔时间单位：小时)
        /// </summary>
        /// <typeparam name="T">具体任务</typeparam>
        public static void AddJobForHours<T>()
             where T : BaseJob, new()
        {
            try
            {
                T job = new T();
                IJobDetail jobDetail = JobBuilder.Create<T>().WithIdentity(job.JobName, job.GropName).Build();
                ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().WithIdentity(job.TriggerName, job.GropName).StartNow()
                                                              .WithSimpleSchedule(x => x.WithIntervalInHours(job.IntervalTime).RepeatForever())
                                                              .Build();
                _scheduler.ScheduleJob(jobDetail, trigger);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region  添加任务(任务间隔时间单位：分钟)
        /// <summary>
        /// 添加任务(任务间隔时间单位：分钟)
        /// </summary>
        /// <typeparam name="T">具体任务</typeparam>
        public static void AddJobForMinutes<T>()
              where T : BaseJob, new()
        {
            try
            {
                T job = new T();
                IJobDetail jobDetail = JobBuilder.Create<T>().WithIdentity(job.JobName, job.GropName).Build();
                ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().WithIdentity(job.TriggerName, job.GropName).StartNow()
                                                              .WithSimpleSchedule(x => x.WithIntervalInMinutes(job.IntervalTime).RepeatForever())
                                                              .Build();
                _scheduler.ScheduleJob(jobDetail, trigger);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region 添加任务(任务间隔时间单位：秒)
        /// <summary>
        /// 添加任务(任务间隔时间单位：秒)
        /// </summary>
        /// <typeparam name="T">具体任务</typeparam>
        public static void AddJobForSeconds<T>()
             where T : BaseJob, new()
        {
            try
            {
                T job = new T();
                IJobDetail jobDetail = JobBuilder.Create<T>().WithIdentity(job.JobName, job.GropName).Build();
                ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().WithIdentity(job.TriggerName, job.GropName).StartNow()
                                                              .WithSimpleSchedule(x => x.WithIntervalInSeconds(job.IntervalTime).RepeatForever())
                                                              .Build();
                _scheduler.ScheduleJob(jobDetail, trigger);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region 根据开始以及结束时间进行添加任务(任务间隔时间单位：小时)
        /// <summary>
        /// 根据开始以及结束时间进行添加任务(任务间隔时间单位：小时)
        /// </summary>
        /// <typeparam name="T">具体任务</typeparam>
        public static void AddJobForHoursStartEndTime<T>()
             where T : BaseJob, new()
        {
            try
            {
                T job = new T();
                IJobDetail jobDetail = JobBuilder.Create<T>().WithIdentity(job.JobName, job.GropName).Build();
                ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().WithIdentity(job.TriggerName, job.GropName).StartAt(job.StartTime).EndAt(job.EndTime)
                                                              .WithSimpleSchedule(x => x.WithIntervalInHours(job.IntervalTime).RepeatForever())
                                                              .Build();
                _scheduler.ScheduleJob(jobDetail, trigger);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region 根据开始以及结束时间进行添加任务(任务间隔时间单位：分钟)
        /// <summary>
        /// 根据开始以及结束时间进行添加任务(任务间隔时间单位：分钟)
        /// </summary>
        /// <typeparam name="T">具体任务</typeparam>
        public static void AddJobForMinutesStartEndTime<T>()
              where T : BaseJob, new()
        {
            try
            {
                T job = new T();
                IJobDetail jobDetail = JobBuilder.Create<T>().WithIdentity(job.JobName, job.GropName).Build();
                ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().WithIdentity(job.TriggerName, job.GropName).StartAt(job.StartTime).EndAt(job.EndTime)
                                                              .WithSimpleSchedule(x => x.WithIntervalInMinutes(job.IntervalTime).RepeatForever())
                                                              .Build();
                _scheduler.ScheduleJob(jobDetail, trigger);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region 根据开始以及结束时间进行添加任务(任务间隔时间单位：秒)
        /// <summary>
        /// 根据开始以及结束时间添加任务(任务间隔时间单位：秒)
        /// </summary>
        /// <typeparam name="T">具体任务</typeparam>
        public static void AddJobForSecondsStartEndTime<T>()
             where T : BaseJob, new()
        {
            try
            {
                T job = new T();
                IJobDetail jobDetail = JobBuilder.Create<T>().WithIdentity(job.JobName, job.GropName).Build();
                ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().WithIdentity(job.TriggerName, job.GropName).StartAt(job.StartTime).EndAt(job.EndTime)
                                                              .WithSimpleSchedule(x => x.WithIntervalInSeconds(job.IntervalTime).RepeatForever())
                                                              .Build();
                _scheduler.ScheduleJob(jobDetail, trigger);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region 根据开始以及结束时间执行指定重复次数进行添加任务(任务间隔时间单位：小时)
        /// <summary>
        /// 根据开始以及结束时间执行指定重复次数进行添加任务(任务间隔时间单位：小时)
        /// </summary>
        /// <typeparam name="T">具体任务</typeparam>
        public static void AddJobForHoursRepeatCount<T>()
             where T : BaseJob, new()
        {
            try
            {
                T job = new T();
                IJobDetail jobDetail = JobBuilder.Create<T>().WithIdentity(job.JobName, job.GropName).Build();
                ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().WithIdentity(job.TriggerName, job.GropName).StartAt(job.StartTime).EndAt(job.EndTime)
                                                              .WithSimpleSchedule(x => x.WithIntervalInHours(job.IntervalTime).WithRepeatCount(job.RepeatCount))
                                                              .Build();
                _scheduler.ScheduleJob(jobDetail, trigger);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region 根据开始以及结束时间执行指定重复次数进行添加任务(任务间隔时间单位：分钟)
        /// <summary>
        /// 根据开始以及结束时间执行指定重复次数进行添加任务(任务间隔时间单位：分钟)
        /// </summary>
        /// <typeparam name="T">具体任务</typeparam>
        public static void AddJobForMinutesRepeatCount<T>()
              where T : BaseJob, new()
        {
            try
            {
                T job = new T();
                IJobDetail jobDetail = JobBuilder.Create<T>().WithIdentity(job.JobName, job.GropName).Build();
                ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().WithIdentity(job.TriggerName, job.GropName).StartAt(job.StartTime).EndAt(job.EndTime)
                                                              .WithSimpleSchedule(x => x.WithIntervalInMinutes(job.IntervalTime).WithRepeatCount(job.RepeatCount))
                                                              .Build();
                _scheduler.ScheduleJob(jobDetail, trigger);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region 根据开始以及结束时间执行指定重复次数进行添加任务(任务间隔时间单位：秒)
        /// <summary>
        /// 根据开始以及结束时间执行指定重复次数进行添加任务(任务间隔时间单位：秒)
        /// </summary>
        /// <typeparam name="T">具体任务</typeparam>
        public static void AddJobForSecondsRepeatCount<T>()
             where T : BaseJob, new()
        {
            try
            {
                T job = new T();
                IJobDetail jobDetail = JobBuilder.Create<T>().WithIdentity(job.JobName, job.GropName).Build();
                ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().WithIdentity(job.TriggerName, job.GropName).StartAt(job.StartTime).EndAt(job.EndTime)
                                                              .WithSimpleSchedule(x => x.WithIntervalInSeconds(job.IntervalTime).WithRepeatCount(job.RepeatCount))
                                                              .Build();
                _scheduler.ScheduleJob(jobDetail, trigger);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region 通过Cron表达式添加任务
        /// <summary>
        /// 通过Cron表达式添加任务
        /// </summary>
        /// <typeparam name="T">具体任务</typeparam>
        public static void AddJobForCron<T>()
            where T : BaseJob, new()
        {
            try
            {
                T job = new T();
                IJobDetail jobDetail = JobBuilder.Create<T>().WithIdentity(job.JobName, job.GropName).Build();

                ICronTrigger trigger = (ICronTrigger)TriggerBuilder.Create()
                                             .WithIdentity(job.TriggerName, job.GropName)
                                             .WithCronSchedule(job.CronExpression)
                                             .Build();
                _scheduler.ScheduleJob(jobDetail, trigger);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion
    }
}
